package midas.mw.crt.common;

import java.util.Date;

/**
 * Defines an IP message used to exchange information between applications 
 * running in the source and destination nodes. The message consists of 
 * source and destination node identifier information, source and 
 * destination application identifier information and the message content. 
 */

public class IPMessage extends CrtMessage implements Cloneable
{	
	/**
	 * Default serial version ID
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * Number of bytes of the data of the whole message 
	 */
	private int totalLength;
	
	/**
	 * Number of parts the whole message is chunked
	 */
	private int numMessages;
	
	/**
	 * Number of order of a part of the message
	 */
	private int numOrder;
	
	
	/** 
	 * Destination node identifier
	 */
	private String destinationNodeId;
	
	/**
	 * Message type
	 */
	private String messageType = "IP_MESSAGE:REQUEST";
	
	/** 
	 * Final destination node identifier. Used with communications through proxy
	 */
	private String finalDestinationNodeId;
	
	/**
	 * Defines the time that the message is valid in the CRT expressed in milliseconds
	 */
	private long timeToLive				= 60 * 5 *  1000;
	
	/**
	 * Defines the date when the message expires
	 */
	private Date expirationDate			= null;
	
	/**
	 * Defines if the message needs delivery confirmation
	 */
	private boolean confirmation		= false;
	
	/**
	 * Defines the priority of the message in order to enqueue it. At the moment, 
	 * three values are allowed: low, medium, high
	 */
	private byte priority				= LOW;
	
	//private byte [] parts				= null;
	/**
	 * Value for low priority in the delivery of messages
	 */
	public static final byte LOW 		= 0;
	
	/**
	 * Value for medium priority in the delivery of messages
	 */
	public static final byte MEDIUM 	= 1;
	
	/**
	 * Value for high priority in the delivery of messages
	 */
	
	public static final byte HIGH 		= 2;
	 
	/**
	 * Constructor - No initiation of attributes.
	 */
	public IPMessage() 
	{
		//No initialisation
		super();
	}
	
	/**
	 * Constructor - initialising all object attributes.
	 * @param sourceNodeId Source MIDAS node identifier value.
	 * @param destinationNodeId Destination MIDAS node identifier value.
	 * @param sourceUserId Source application identifier value.
	 * @param destinationUserId Destination application identifier value.
	 * @param messageContent Message content value.
	 */
	public IPMessage(String sourceNodeId, String destinationNodeId, String sourceUserId, String destinationUserId, byte[] messageContent) 
	{
		super(sourceNodeId, sourceUserId, destinationUserId, messageContent);		
		this.destinationNodeId 	= destinationNodeId;	
	}
	
	/**
	 * @deprecated Constructor - initialising all object attributes.
	 * @param sourceNodeId Source MIDAS node identifier value.
	 * @param destinationNodeId Destination MIDAS node identifier value.
	 * @param sourceUserId Source application identifier value.
	 * @param destinationUserId Destination application identifier value.
	 * @param messageContent Message content value.
	 */
	public IPMessage(String sourceNodeId, String destinationNodeId, String sourceUserId, String destinationUserId, String messageContent) 
	{
		super(sourceNodeId, sourceUserId, destinationUserId, messageContent);		
		this.destinationNodeId 	= destinationNodeId;	
	}
	
	/**
	 * Constructor - initialising all object attributes.
	 * @param sourceNodeId Source MIDAS node identifier value.
	 * @param destinationNodeId Destination MIDAS node identifier value
	 * @param sourceUserId Source CRT user identifier value.
	 * @param destinationUserId Destination CRT user identifier value.
	 * @param messageContent Message content value.
	 * @param timeToLive Time that the message is valid in the CRT
	 * @param priority Priority of the message
	 */
	public IPMessage(String sourceNodeId, String destinationNodeId, String sourceUserId, String destinationUserId, byte[] messageContent, long timeToLive, byte priority, boolean confirmation) {
		super(sourceNodeId, sourceUserId, destinationUserId, messageContent);
		this.destinationNodeId 	= destinationNodeId;
		this.timeToLive 		= timeToLive;
		this.priority 			= priority;
		this.confirmation		= confirmation;
	}
	
	/**
	 * @deprecated Constructor - initialising all object attributes.
	 * @param sourceNodeId Source MIDAS node identifier value.
	 * @param destinationNodeId Destination MIDAS node identifier value
	 * @param sourceUserId Source CRT user identifier value.
	 * @param destinationUserId Destination CRT user identifier value.
	 * @param messageContent Message content value.
	 * @param timeToLive Time that the message is valid in the CRT
	 * @param priority Priority of the message
	 */
	public IPMessage(String sourceNodeId, String destinationNodeId, String sourceUserId, String destinationUserId, String messageContent, long timeToLive, byte priority) {
		super(sourceNodeId, sourceUserId, destinationUserId, messageContent);
		this.destinationNodeId 	= destinationNodeId;
		this.timeToLive 		= timeToLive;
		this.priority 			= priority;
	}

	/**
	 * Returns the associated priority in the delivery of the message
	 * @return The associated priority in the delivery of the message
	 */
	public byte getPriority() 
	{
		return priority;
	}
	
	/**
	 * Sets the associated priority in the delivery of the message
	 * @param priority The associated priority in the delivery of the message
	 */
	public void setPriority(byte priority) 
	{
		this.priority = priority;
	}
	
	/**
	 * Returns the time the message is valid in the CRT
	 * @return The time the message is valid in the CRT
	 */
	public long getExpirationTime() 
	{
		return timeToLive;
	}
	
	/**
	 * Sets the time the message is valid in the CRT
	 * @param expirationTime The time the message is valid in the CRT
	 */
	public void setExpirationTime(long expirationTime) 
	{
		this.timeToLive = expirationTime;
	}
	
	/**
	 * Returns the time the message is valid in the CRT
	 * @return The date till the message is valid in the CRT
	 */
	public Date getExpirationDate() 
	{
		return expirationDate;
	}
	
	/**
	 * Sets the time the message is valid in the CRT
	 * @param expirationDate The date till the message is valid in the CRT
	 */
	public void setExpirationDate(Date expirationDate) 
	{
		this.expirationDate = expirationDate;
	}
	
	/**
	 * Shows if the message needs delivery confirmation
	 * @return True if the message needs delivery conformation; false otherwise
	 */
	public boolean getConfirmation() 
	{
		return confirmation;
	}
	
	/**
	 * Sets if the message needs delivery confirmation
	 * @param confirmation True if the message needs delivery conformation; false otherwise
	 */
	public void setConfirmation(boolean confirmation) 
	{
		this.confirmation = confirmation;
	}
	
	
	/**
	 * Gets the destination MIDAS node identifier value.
	 * @return Destination MIDAS node identifier value.
	 */
	public String getDestinationNodeId()
	{
		return destinationNodeId;
	}	
	
	/**
	 * Sets the MIDAS node identifier value of the final destination
	 * @param destinationNodeId MIDAS node identifier value of the final destination
	 */
	public void setDestinationNodeId(String destinationNodeId) {
		this.destinationNodeId = destinationNodeId;
	}	
	
	/**
	 * Gets the MIDAS node identifier value of the final destination
	 * @return Destination MIDAS node identifier value of the final destination
	 */
	public String getFinalDestinationNodeId()
	{
		return finalDestinationNodeId;
	}	
	
	/**
	 * Sets the destination MIDAS node identifier value.
	 * @param finalDestinationNodeId Destination MIDAS node identifier value.
	 */
	public void setFinalDestinationNodeId(String finalDestinationNodeId) {
		this.finalDestinationNodeId = finalDestinationNodeId;
	}	
	
	/**
	 * Gets the message type of the IPMessage
	 * @return The message type of the IPMessage
	 */
	public String getMessageType()
	{
		return messageType;
	}	
	
	/**
	 * Sets the message type of the IPMessage
	 * @param messageType Message type
	 */
	public void setMessageType(String messageType) {
		this.messageType = messageType;
	}	
	
	/**
	 * Sets the number of parts a whole IPMessage is divided
	 * @param numMessages Number of parts a whole IPMessage is divided
	 */
	public void setNumMessages(int numMessages)
	{
		this.numMessages = numMessages;
	}
	
	/**
	 * Gets the number of parts a whole IPMessage is divided
	 * @return The number of parts a whole IPMessage is divided
	 */
	public int getNumMessages()
	{
		return numMessages;
	}
	
	/**
	 * Sets the number of order of a IPMessage into the whole IPMessage
	 * @param numOrder Number of order of the IPMessage into the whole message
	 */
	public void setNumOrder(int numOrder)
	{
		this.numOrder = numOrder;
	}
	
	/**
	 * Gets the number of order of a IPMessage into the whole IPMessage
	 * @return The number of order of the IPMessage into the whole message
	 */
	public int getNumOrder()
	{
		return numOrder;
	}
	
	/**
	 * Sets the number of bytes of the data of the whole IPMessage 
	 * @param totalLength Number of bytes of the data of the whole IPMessage 
	 */
	public void setTotalLength(int totalLength)
	{
		this.totalLength = totalLength;
	}
	
	/**
	 * Gets the number of bytes of the data of the whole IPMessage 
	 * @return Number of bytes of the data of the whole IPMessage 
	 */
	public int getTotalLength()
	{
		return totalLength;
	}
	
	/*public void setParts(byte[] parts)
	{
		this.parts = parts;
	}
	
	public byte[] getParts()
	{
		return parts;
	}
	
	public ArrayList getUncompleteParts()
	{
		ArrayList temp = new ArrayList();
		for (int i=0; i<parts.length; i++)
		{
			if (parts[i] == 0)
				temp.add(i);
		}
		return temp;
	}*/
	
	/**
	 * Creates and returns a copy of the IPMessage
	 */
	public Object clone(){
		Object obj = null;
        try{
            obj = super.clone();            
        }catch(CloneNotSupportedException ex){
            ex.printStackTrace();
        }
        return obj;
    }
	
	/**
	 * Shows the features of the message. It is only useful for testing mode
	 * 
	 * @return String containing the features of the message
	 */
	public String msgToString()
	{
		return "-mensaje: " + 	messageType + "," + 
								sourceNodeId + "," +
								destinationNodeId + "," + 
								finalDestinationNodeId + "," +
								sourceUserId + "," +
								destinationUserId + "," +
								confirmation + "," +
								timeToLive + "," + 
								priority + "," + 
								messageId + "," + 
								totalLength + "," + 
								numMessages + "," +
								numOrder;// + "," +
								//new String(messageContent) + "-";
	}
}